package com.photoeditor.demo.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapRegionDecoder;
import android.text.TextUtils;

import com.common.base.ComponentContext;
import com.photoeditor.demo.util.gallery.util.ImageWorker;

import java.io.File;
import java.util.LinkedHashMap;

public class BitmapCache extends ImageWorker {
	public static final String IMAGE_CACHE_DIR = "preview";
	private File mImageCacheDir;
	private ImageCache mImageCache;
    private ImageCache.ImageCacheParams mImageCacheParams;
    
    private static boolean CHECK_JOURNAL = true;
    
 	private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 50; // 50MB
 	
 	private static final int DEFAULT_MOMERY_CACHE_SIZE = 1024 * 1024 * 30; // 20MB
 	
 	/**
 	 * 10个缓存可能会在多次左右滑动时被回收掉
 	 */
 	private static final int DEFAULT_DECODER_SIZE = 12;
 	
 	/**
 	 * 对他的一些方法进行了重写 线程安全的
 	 */
 	private LinkedHashMap<String, BitmapRegionDecoder> mDecoderCache;
 	
 	private Object mLockObject = new Object();
 	
	private void init(Context context) {
		mImageCacheDir = ImageCache.getDiskCacheDir(context, IMAGE_CACHE_DIR);
		if (!mImageCacheDir.exists()) {
			mImageCacheDir.mkdirs();
		}
		mDecoderCache = new LinkedHashMap<String, BitmapRegionDecoder>(DEFAULT_DECODER_SIZE, 1, true){

			/**
			 * serialVersionUID
			 */
			private static final long serialVersionUID = 1L;
			
			@Override
			protected boolean removeEldestEntry(Entry<String, BitmapRegionDecoder> eldest) {
				synchronized (mLockObject) {
					if(size() > DEFAULT_DECODER_SIZE){
						return true;
					}
					return super.removeEldestEntry(eldest);
				}
			}
			
			@Override
			public BitmapRegionDecoder get(Object key) {
				synchronized (mLockObject) {
					return super.get(key);
				}
			}
			
			@Override
			public BitmapRegionDecoder put(String key, BitmapRegionDecoder value) {
				synchronized (mLockObject) {
					return super.put(key, value);
				}
			}
			
			@Override
			public void clear() {
				synchronized (mLockObject) {
					super.clear();
				}
			}
			
			@Override
			public BitmapRegionDecoder remove(Object key) {
				synchronized (mLockObject) {
					BitmapRegionDecoder decoder = super.remove(key);
					decoder.recycle();
					return decoder;
				}
			}
		};
	}
	
	public BitmapCache(Context context) {
		super(context);
		init(context);
		/**
		 * 传入目录名称
		 */
		mImageCacheParams = new ImageCache.ImageCacheParams(
				ComponentContext.getContext(), IMAGE_CACHE_DIR);
		mImageCacheParams.compressFormat = CompressFormat.JPEG;
        mImageCacheParams.compressQuality = 100;
        mImageCacheParams.diskCacheSize = DEFAULT_DISK_CACHE_SIZE;
        mImageCacheParams.memCacheSize = DEFAULT_MOMERY_CACHE_SIZE;
        // Set memory cache to 25% of mem class
        mImageCacheParams.setMemCacheSizePercent(ComponentContext.getContext(), 0.25f);
        if (mImageCache == null) {
            addImageCache(mImageCacheParams, CHECK_JOURNAL);
            mImageCache = getImageCache();
        } else {
            setImageCache(mImageCache);
            // because we can only use addImageCache to init Disk Cache, so here
            // we call it again
            addImageCache(mImageCacheParams, CHECK_JOURNAL);
        }
        CHECK_JOURNAL = false;
	}

	/**
	 * do nothing
	 */
	@Override
	protected Bitmap processBitmap(Object data, int degree,
			AsyncTask<Object, Object, Bitmap> bitmapWorkerTask) {
		return null;
	}
	
	/**
	 * 从缓存中获取Bitmap
	 * @param pathString
	 * @return
	 */
	public Bitmap getBitmapFromCache(String pathString){
		if(!TextUtils.isEmpty(pathString)){
			Bitmap bitmap = mImageCache.getBitmapFromMemCache(pathString);
			if(bitmap == null || bitmap.isRecycled()){
				bitmap = mImageCache.getBitmapFromDiskCache(pathString);
			}
			return bitmap;
		}
		return null;
	}
	
	/**
	 * 将Bitmap加入到缓存中
	 * @param data
	 * @param bitmap
	 * @param addToMemoryCache
	 * @param isNeedAddDiskCache
	 */
	public void addBitmapToCache(String data, Bitmap bitmap, boolean addToMemoryCache, boolean isNeedAddDiskCache){
		if(bitmap != null && !bitmap.isRecycled() && !TextUtils.isEmpty(data)){
			mImageCache.addBitmapToCache(data, bitmap, addToMemoryCache, isNeedAddDiskCache);
		}
	}
	
	public void addDecoderToCache(String path, BitmapRegionDecoder decoder){
		if(decoder != null && !decoder.isRecycled() && !TextUtils.isEmpty(path)){
			mDecoderCache.put(path, decoder);
		}
	}
	
	public BitmapRegionDecoder getDecoderFormCache(String path){
		if(!TextUtils.isEmpty(path)){
			return mDecoderCache.get(path);
		}
		return null;
	}
}
